package com.link.base.base.common.utils;

import com.link.core.cllog.LCLogger;
import com.link.core.basic.model.BasicModel;
import com.link.core.basic.query.ExportColumn;
import com.link.core.basic.query.QueryParams;
import com.link.core.basic.service.BasicService;
import com.link.core.util.DateUtil;
import com.link.core.util.DecimalUtil;
import com.link.core.util.ReflectUtil;
import com.link.core.util.StringUtils;
import com.link.ext.basic.model.BasicBaseModel;
import com.link.ext.basic.model.BasicExtModel;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.List;

/**
 * Copyright  hande Company. All Rights Reserved.
 *
 * @author  Li Yang
 * @date:   2018-10-22
 * @version 1.0
 */
public class QueryAndWriteData implements Runnable/*Callable<String>*/ {

    private static final Logger logger = LogManager.getLogger(QueryAndWriteData.class);

    private BasicService basicService;

    private BasicModel entity;

    private int pageSize;

    private QueryParams qps;

    private int page;

    private Sheet sheet;

    public QueryAndWriteData(BasicService basicService, BasicModel entity, QueryParams qps, int pageSize, int page, Sheet sheet) {
        this.basicService = basicService;
        this.entity = entity;
        this.pageSize = pageSize;
        this.page = page;
        this.qps = qps;
        this.sheet = sheet;
    }

    @Override
    public void run() {
        List<BasicModel> resultList = null;
        try {
            //copy一个新的entity对象作为参数
            BasicModel newEntity = (BasicModel) entity.deepClone();
            newEntity.setPage(this.page);
            //查询数据
            resultList = basicService.queryByExamplePage(newEntity);
        } catch (Exception e) {
            LCLogger.error().withMessageKey("run")
                    .withMessage(e.getMessage()).flush();
        }
        //生成workbook对象
        if (pageSize == -1) {
            writeExcel(resultList, 1);
        } else {
            writeExcel(resultList, (this.page - 1) * pageSize + 1);
        }
    }

    /**
     * @author Li Yang
     * created 2018-10-22
     * 写excel文件
     * 这里面的代码是直接拿的之前的生成导出数据的代码
     */
    public void writeExcel(List<BasicModel> contentList, int excelStartIndex) {
        List<ExportColumn> headList = qps.getExportColumns();
        try {
            //---------------------写行---------------------
            Row row;
            int rowIndex = excelStartIndex;
            //循环写行数据
            for (int i = 0; contentList != null && i < contentList.size(); i++) {
                //创建一个表格行
                row = getRow(this.sheet, rowIndex);
                Object exportData = contentList.get(i);
                //获取当前返回值对象对应的类
                Class<?> clazz = exportData.getClass();
                //根据列顺序把导出数据写到文件中
                int colLineSize = headList.size();
                String[] sb = new String[colLineSize];
                for (int j = 0; j < colLineSize; j++) {
                    ExportColumn col = headList.get(j);
                    String field = col.getField();
                    //获取当前返回值对象相关属性值
                    Field propertyField;
                    Class<?> propertyType = null;
                    Object colData = null;
                    propertyField = ReflectUtil.getField(clazz, field);
                    propertyType = propertyField.getType();
                    colData = getProperty(exportData, field);

                    String renderedData = "";
                    if (colData == null) {
                        renderedData = "";
                    } else {
                        if (propertyType == Integer.class) {
                            renderedData = DecimalUtil.integerFormat(colData);
                        } else if (propertyType == Long.class) {
                            renderedData = DecimalUtil.integerFormat(colData);
                        } else if (propertyType == Float.class) {
                            renderedData = DecimalUtil.decimalFormat(colData);
                        } else if (propertyType == Double.class) {
                            renderedData = DecimalUtil.decimalFormat(colData);
                        } else if (propertyType == Date.class) {
                            renderedData = DateUtil.dateToStr((Date) colData, "yyyy-MM-dd HH:mm:ss");
                        } else if (propertyType == String.class) {
                            renderedData = colData.toString();
                        } else {
                            logger.warn("不支持的数据类型");
                            renderedData = colData.toString();
                        }
                    }
                    if (StringUtils.isNotBlank(col.getLov())) {
                        //值列表转换
                        sb[j] = col.getLovShowName(renderedData);
                    } else {
                        sb[j] = renderedData;
                    }
                    Cell cell = row.createCell(j);
                    cell.setCellValue(sb[j]);
                }
                rowIndex += 1;
            }
        } catch (Exception e) {
            LCLogger.error().withMessageKey("writeExcel")
                    .withMessage(e.getMessage()).flush();
        }
    }

    private static synchronized Row getRow(Sheet sheet, int rowIndex) {
        return sheet.createRow(rowIndex);
    }

    public static Object getProperty(Object exportData, String field) throws IllegalAccessException,
            InvocationTargetException {
        Object colData = "";
        try {
            colData = PropertyUtils.getSimpleProperty(exportData, field);
        } catch (NoSuchMethodException e) {
            logger.debug("Export Ext Column");
            if (exportData instanceof BasicBaseModel) {
                List<BasicExtModel> extList = ((BasicBaseModel) exportData).getExtList();
                if (extList != null) {
                    for (BasicExtModel ext : extList) {
                        if (StringUtils.equals(field, ext.getName())) {
                            colData = ext.getValue();
                            break;
                        }
                    }
                }
            } else {
                LCLogger.error().withMessageKey("getProperty")
                        .withMessage(e.getMessage()).flush();
            }
        }
        return colData;
    }
}
